/**
 * 注意：需要挂在场景节点上使用
 * 
 * 使用方法：将脚本挂在任意节点上(建议挂在canvas节点上)，分别输入普通音频和背景音乐的个数，拉入对应的音频资源就可以了，
 * 还可以在界面动态修改每个音频文件的循环播放模式,音量和是否能多重播放，否则用默认值，（建议用默认值）
 * 
 * 说明：音频文件分为2个大类，背景音乐和普通的音频文件，此脚本对音频文件处理后得到以下效果：
 * 1.背景音乐只能有一个在播放，开始播放时会先停止当前正在播放的背景音乐（没有背景音乐在播放就不处理），然后播放选中的背景音乐，默认循环播放，音量1
 * 2.普通音频可以多个不同的音频同时播放，相同音频是否能多重播放取决于canMultiPlay参数，默认不能多重播放，默认不循环播放，音量1
 * 3.背景音乐和普通音频可以同时播放，互不影响
 * 
 * api用法说明： 例如对于一个叫"luck"的背景音乐， 2个分别叫"pass"和"buttonClick"的普通音频
 * 1.背景音乐常用api： playBGM(),  playBGMluck() 用于多背景音乐的选播, playBGMluck(true，1.0) 用于调节播放的循环模式和音量, stopBGM(), pauseBGM(), resumeBGM(),
 * 2.普通音频常用api： 类似(play + 文件名) 如：playpass(false, 1.0) 参数可以没有，用界面默认参数 stopbuttonClick(), pausepass(), resumebuttonClick() play类型可以传入参数来控制循环模式和音量，否则用默认值
 * 3.通用的共同控制api：
 * （1）批量普通音频控制：pauseAllMusic()， resumeAllMusic()， stopAllMusic()
 * （2）批量所有音频控制（普通音频 + 背景音乐）: pauseAll(), resumeAll(), stopAll()
 */

/**加载模式列表 Static 静态加载 Dynamic 动态加载（包括本地和远程动态加载） */
var loadType = cc.Enum({
    Static: 0,
    Dynamic: 1
});

//普通音频类型，不同音频可以同时播放，默认相同音频不能多重播放
//默认不循环，音量为1
var Music = cc.Class({
    name: 'Music',
    properties: {
        loadType: {
            default: loadType.Static,
            type: loadType,
            tooltip: "加载模式：Static静态加载，面板拖入音频资源的加载方式  Dynamic动态加载，resource目录动态加载方式和从远程服务器加载方式，可以控制加载时机",
            notify(){
                if(this.loadType === loadType.Static){
                    this.url = "";
                    this.musicName = "";
                    //隐藏url，musicName属性
                    cc.Class.attr(Music, "clip", {visible: true});
                    cc.Class.attr(Music, "url", {visible: false});
                    cc.Class.attr(Music, "musicName", {visible: false});
                }else if(this.loadType === loadType.Dynamic){
                    this.clip = null;
                    //隐藏clip属性
                    cc.Class.attr(Music, "clip", {visible: false});
                    cc.Class.attr(Music, "url", {visible: true});
                    cc.Class.attr(Music, "musicName", {visible: true});
                }
            }
        },
        clip: {
            default: null,
            type: cc.AudioClip,
            tooltip: "音频资源文件，用于Static静态加载",
            visible: true,
            notify(){
                if(this.clip){
                    this.loadType = loadType.Static
                }
            }
        },
        url: {
            default: "",
            tooltip: "音频资源文件对应路径，用于Dynamic动态加载（本地和远程）",
            visible: false,
            notify(){
                if(this.url){
                    this.loadType = loadType.Dynamic
                }
            }
        },
        musicName: {
            default: "",
            tooltip: "音频文件名字，用于Dynamic动态加载（本地和远程）",
            visible: false,
            notify(){
                if(this.musicName){
                    this.loadType = loadType.Dynamic
                }
            }
        },

        loop: {
            default: false,
            tooltip: "是否循环播放，默认为false",
        },
        volume: {
            default: 1.0,
            type: cc.Float,
            range: [0, 10],
            tooltip: "播放音量大小，默认为1",
        },
        canMultiPlay: {
            default: false,
            tooltip: "是否能多重播放相同音频，默认为false",
        },
    }
});

//背景音乐类型，只能有一个背景音乐播放
//默认循环，音量为1
var BGM = cc.Class({
    name: 'BGM',
    properties: {
        loadType: {
            default: loadType.Static,
            type: loadType,
            tooltip: "加载模式：Static静态加载，面板拖入音频资源的加载方式  Dynamic动态加载，resource目录动态加载方式和从远程服务器加载方式，可以控制加载时机",
            notify(){
                if(this.loadType === loadType.Static){
                    this.url = "";
                    this.musicName = "";
                    //隐藏url，musicName属性
                    cc.Class.attr(BGM, "clip", {visible: true});
                    cc.Class.attr(BGM, "url", {visible: false});
                    cc.Class.attr(BGM, "musicName", {visible: false});
                }else if(this.loadType === loadType.Dynamic){
                    this.clip = null;
                    //隐藏url，musicName属性
                    cc.Class.attr(BGM, "clip", {visible: false});
                    cc.Class.attr(BGM, "url", {visible: true});
                    cc.Class.attr(BGM, "musicName", {visible: true});
                }
            }
        },
        clip: {
            default: null,
            type: cc.AudioClip,
            tooltip: "音频资源文件，用于Static静态加载",
            visible: true,
            notify(){
                if(this.clip){
                    this.loadType = loadType.Static
                }
            }
        },
        url: {
            default: "",
            tooltip: "音频资源文件对应路径，用于Dynamic动态加载（本地和远程）",
            visible: false,
            notify(){
                if(this.url){
                    this.loadType = loadType.Dynamic
                }
            }
        },
        musicName: {
            default: "",
            tooltip: "音频文件名字，用于Dynamic动态加载（本地和远程）",
            visible: false,
            notify(){
                if(this.musicName){
                    this.loadType = loadType.Dynamic
                }
            }
        },

        loop: {
            default: true,
            tooltip: "是否循环播放，默认为true",
        },
        volume: {
            default: 1.0,
            type: cc.Float,
            range: [0, 10],
            tooltip: "播放音量大小，默认为1",
        }
    }
});

var self = null;
cc.Class({
    extends: cc.Component,

    properties: {
        BGMArr: {
            default: [],
            type: BGM,
            tooltip: "输入背景音乐个数",
        },

        MusicArr: {
            default: [],
            type: Music,
            tooltip: "输入普通音频个数",
        }
    },

    onLoad () {
        self = this;
        //是否为静音模式
        this.isMute = false;

        //正在播放的背景音乐id
        this.playBGMId = 0;
        //背景音乐配置错误性检查
        for(var n = 0; n < this.BGMArr.length; n++){
            switch(this.BGMArr[n].loadType){
                case loadType.Static:
                    if(this.BGMArr[n].clip === null){
                        console.error("静态加载背景音乐缺少音频文件！！！");
                    }
                    break;
                case loadType.Dynamic:
                    if(this.BGMArr[n].url === "" || this.BGMArr[n].musicName === ""){
                        console.error("动态加载背景音乐缺少路径或者音乐名字！！！");
                    }
                    break;
                default:
                    console.error("背景音乐加载类型错误！！！");
            }
        } 

        //正在播放的音频数组
        this.playArr = [];
        //普通音频配置错误性检查
        for(var i = 0; i < this.MusicArr.length; i++){
            switch(this.MusicArr[i].loadType){
                case loadType.Static:
                    if(this.MusicArr[i].clip === null){
                        console.error("静态加载普通音频缺少音频文件！！！");
                    }
                    break;
                case loadType.Dynamic:
                    if(this.MusicArr[i].url === "" || this.MusicArr[i].musicName === ""){
                        console.error("动态加载普通音频缺少路径或者音乐名字！！！");
                    }
                    break;
                default:
                    console.error("普通音频加载类型错误！！！");
            }
        }  
    },

    //清除播放列表对应id的记录
    removePlayArrById(id){
        for(var n = 0; n < this.playArr.length; n++){
            if(this.playArr[n].id === id){
                this.playArr.splice(n, 1);
                break;
            }
        }
    },
    
    //播放背景音乐，3参数都可选，默认播放第一个背景音乐
    //name 背景音乐的名字，默认为第一个背景音乐  loop 背景音乐是否循环，默认true  volume 背景音乐的音量，默认1
    playBGM(name, loop, volume){
        if(this.isMute){
            return;
        }
        //根据name找到对应的配置信息
        var BGMInfo = null;
        if(name === undefined){
            BGMInfo = this.BGMArr[0];
        }else{//遍历数组找对应信息
            for(var n = 0; n < this.BGMArr.length; n++){
                if((this.BGMArr[n].clip && name === this.BGMArr[n].clip.name) || name === this.BGMArr[n].musicName){
                    BGMInfo = this.BGMArr[n];
                    break;
                }
            }
        }
        if(BGMInfo == null){
            console.error("没找到对应的背景音乐！！！");
        }else{//可以播放
            //参数检查
            if(loop === undefined){
                loop = BGMInfo.loop;
            }
            if(volume === undefined){
                volume = BGMInfo.volume;
            }
            if(!loop){
                console.warn("当前的背景音乐为非循环播放模式!");
            }
            if(BGMInfo.loadType === loadType.Static){//静态加载方式
                //播放背景音乐会先关闭当前正在播放的背景音乐
                //关闭当前正在播放的背景音乐
                this.stopBGM();
                this.playBGMId = cc.audioEngine.play(BGMInfo.clip, loop, volume);
            }else{//动态加载方式
                if(this["DynamicBGM" + BGMInfo.musicName]){//已经加载过了
                    //关闭当前正在播放的背景音乐
                    this.stopBGM();
                    this.playBGMId = cc.audioEngine.play(this["DynamicBGM" + BGMInfo.musicName], loop, volume);
                }else{//第一次动态加载
                    if(BGMInfo.url.indexOf("http") > -1){//远程加载
                        cc.loader.load(BGMInfo.url, (err, clip)=> {
                            if(err){
                                console.error(err.message || err);
                                return;
                            }
                            //记录当前的音频
                            this["DynamicBGM" + BGMInfo.musicName] = clip;
                            //关闭当前正在播放的背景音乐
                            this.stopBGM();
                            this.playBGMId = cc.audioEngine.play(clip, loop, volume);
                        });
                    }else{//本地加载
                        cc.loader.loadRes(BGMInfo.url, cc.AudioClip, (err, clip) => {
                            if(err){
                                console.error(err.message || err);
                                return;
                            }
                            //记录当前的音频
                            this["DynamicBGM" + BGMInfo.musicName] = clip;
                            //关闭当前正在播放的背景音乐
                            this.stopBGM();
                            this.playBGMId = cc.audioEngine.play(clip, loop, volume);
                        });
                    }
                }
            }
        }
    },

    //播放普通音乐，name必须，loop, volume可选
    //name 普通音乐的名字，  loop 普通音乐是否循环，默认false  volume 普通音乐的音量，默认1
    play(name, loop, volume){
        if(this.isMute){
            return;
        }
        //根据name找到对应的配置信息
        var MusicInfo = null;
        if(name === undefined){
            console.error("请输入要播放的普通音乐的名字！！！");
            return;
        }else{//遍历数组找对应信息
            for(var n = 0; n < this.MusicArr.length; n++){
                if((this.MusicArr[n].clip && name === this.MusicArr[n].clip.name) || name === this.MusicArr[n].musicName){
                    MusicInfo = this.MusicArr[n];
                    break;
                }
            }
        }
        if(MusicInfo == null){
            console.error("没找到对应的普通音乐！！！");
        }else{//可以播放
            //参数检查
            if(loop === undefined){
                loop = MusicInfo.loop;
            }
            if(volume === undefined){
                volume = MusicInfo.volume;
            }
            if(loop){
                console.warn("当前的普通音乐为循环播放模式!");
            }
            if(MusicInfo.loadType === loadType.Static){//静态加载方式
                //是否关闭相同音频
                if(!MusicInfo.canMultiPlay){
                    this.stop(MusicInfo.clip.name);
                }
                var id = cc.audioEngine.play(MusicInfo.clip, loop, volume);
                cc.audioEngine.setFinishCallback(id, ()=>{
                    //播放完清理数组
                    this.removePlayArrById(id);
                });
                //保存播放音频的id和clip名字
                var play = {
                    id: id,
                    name: MusicInfo.clip.name
                };
                this.playArr.push(play);
            }else{//动态加载方式
                if(this["DynamicMusic" + MusicInfo.musicName]){//已经加载过了
                    //是否关闭相同音频
                    if(!MusicInfo.canMultiPlay){
                        this.stop(MusicInfo.musicName);
                    }
                    var id = cc.audioEngine.play(this["DynamicMusic" + MusicInfo.musicName], loop, volume);
                    cc.audioEngine.setFinishCallback(id, ()=>{
                        //播放完清理数组
                        this.removePlayArrById(id);
                    });
                    //保存播放音频的id和clip名字
                    var play = {
                        id: id,
                        name: MusicInfo.musicName
                    };
                    this.playArr.push(play);
                }else{//第一次动态加载
                    if(MusicInfo.url.indexOf("http") > -1){//远程加载
                        cc.loader.load(MusicInfo.url, (err, clip)=> {
                            if(err){
                                console.error(err.message || err);
                                return;
                            }
                            //记录当前的音频
                            this["DynamicMusic" + MusicInfo.musicName] = clip;
                            //是否关闭相同音频
                            if(!MusicInfo.canMultiPlay){
                                this.stop(MusicInfo.musicName);
                            }
                            var id = cc.audioEngine.play(clip, loop, volume);
                            cc.audioEngine.setFinishCallback(id, ()=>{
                                //播放完清理数组
                                this.removePlayArrById(id);
                            });
                            //保存播放音频的id和clip名字
                            var play = {
                                id: id,
                                name: MusicInfo.musicName
                            };
                            this.playArr.push(play); 
                        });
                    }else{//本地加载
                        cc.loader.loadRes(MusicInfo.url, cc.AudioClip, (err, clip) => {
                            if(err){
                                console.error(err.message || err);
                                return;
                            }
                            //记录当前的音频
                            this["DynamicMusic" + MusicInfo.musicName] = clip;
                            //是否关闭相同音频
                            if(!MusicInfo.canMultiPlay){
                                this.stop(MusicInfo.musicName);
                            }
                            var id = cc.audioEngine.play(clip, loop, volume);
                            cc.audioEngine.setFinishCallback(id, ()=>{
                                //播放完清理数组
                                this.removePlayArrById(id);
                            });
                            //保存播放音频的id和clip名字
                            var play = {
                                id: id,
                                name: MusicInfo.musicName
                            };
                            this.playArr.push(play); 
                        });
                    }
                }
            }
        }
    },

    //停止指定音频 name 音频名字，必需
    stop(name){
        if(name === undefined){
            console.error("请输入停止音频的名字！！！");
            return;
        }
        for(var n = 0; n < this.playArr.length; n++){
            if(this.playArr[n].name === name){
                cc.audioEngine.stop(this.playArr[n].id);
                this.playArr.splice(n, 1);
                n--;
            }
        }
    },

    //暂停指定音频 name 音频名字，必需
    pause(name){
        if(name === undefined){
            console.error("请输入暂停音频的名字！！！");
            return;
        }
        for(var m = 0; m < this.playArr.length; m++){
            if(this.playArr[m].name === name){
                cc.audioEngine.pause(this.playArr[m].id);
            }
        }
    },

    //恢复指定音频 name 音频名字，必需
    resume(name){
        if(name === undefined){
            console.error("请输入恢复音频的名字！！！");
            return;
        }
        if(this.isMute){
            return;
        }
        for(var t = 0; t < this.playArr.length; t++){
            if(this.playArr[t].name === name){
                cc.audioEngine.resume(this.playArr[t].id);
            }
        }
    },

    //暂停播放所有正在播放的普通音频
    pauseAllMusic(){
        for(var i = 0; i < this.playArr.length; i++){
            cc.audioEngine.pause(this.playArr[i].id);
        }
    },
    //恢复播放所有普通音频
    resumeAllMusic(){
        if(this.isMute){
            return;
        }
        for(var i = 0; i < this.playArr.length; i++){
            cc.audioEngine.resume(this.playArr[i].id);
        }
    },
    //停止播放所有普通音频
    stopAllMusic(){
        for(var i = 0; i < this.playArr.length; i++){
            cc.audioEngine.stop(this.playArr[i].id);
        }
        this.playArr = [];
    },


    //暂停正在播放的背景音乐
    pauseBGM(){
        cc.audioEngine.pause(this.playBGMId);
    },
    //恢复播放背景音乐
    resumeBGM(){
        if(this.isMute){
            return;
        }
        cc.audioEngine.resume(this.playBGMId);
    },
    //停止正在播放的背景音乐
    stopBGM(){
        if(this.playBGMId > 0){
            cc.audioEngine.stop(this.playBGMId);
        }
    },


    //暂停播放所有声音，包括普通音频和背景音乐
    pauseAll(){
        this.pauseAllMusic();
        this.pauseBGM();
    },
    //恢复播放所有声音，包括普通音频和背景音乐
    resumeAll(){
        if(this.isMute){
            return;
        }
        this.resumeAllMusic();
        this.resumeBGM();
    },
    //停止播放所有声音，包括普通音频和背景音乐
    stopAll(){
        this.stopAllMusic();
        this.stopBGM();
    },

    //设置静音模式 会暂停背景音乐 停止普通音频  不能播放和恢复所有音频
    muteMode(){
        this.isMute = true;
        this.pauseBGM();
        this.stopAllMusic();
    },

    //恢复正常模式 会恢复背景音乐 可以播放所有音频
    normalMode(){
        this.isMute = false;
        this.resumeBGM();
    },

    //模式切换，在静音模式和普通模式之间切换
    modeChange(){
        this.isMute = !this.isMute;
        if(this.isMute){
            this.muteMode();
        }else{
            this.normalMode();
        }
    },

    //加载背景音乐 name背景音乐的名字，可选，默认为第一个背景音乐
    loadBGM(name){
        var BGMInfo = null;
        if(name === undefined){
            BGMInfo = this.BGMArr[0];
        }else{//遍历数组找对应信息
            for(var n = 0; n < this.BGMArr.length; n++){
                if((this.BGMArr[n].clip && name === this.BGMArr[n].clip.name) || name === this.BGMArr[n].musicName){
                    BGMInfo = this.BGMArr[n];
                    break;
                }
            }
        }
        if(BGMInfo == null){
            console.error("没找到要加载的背景音乐！！！");
        }else{
            if(BGMInfo.url){
                if(BGMInfo.url.indexOf("http") > -1){//远程加载
                    cc.loader.load(BGMInfo.url, (err, clip)=> {
                        if(err){
                            console.error(err.message || err);
                            return;
                        }
                        //记录当前的音频
                        this["DynamicBGM" + BGMInfo.musicName] = clip;
                    });
                }else{//本地加载
                    cc.loader.loadRes(BGMInfo.url, cc.AudioClip, (err, clip) => {
                        if(err){
                            console.error(err.message || err);
                            return;
                        }
                        //记录当前的音频
                        this["DynamicBGM" + BGMInfo.musicName] = clip;
                    });
                }
            }else{
                console.error("要加载的背景音乐url没找到！！！");
            }
        }
    },

    //加载普通音乐 name普通音乐的名字，必须
    loadMusic(name){
        var MusicInfo = null;
        if(name === undefined){
            console.error("请输入要加载普通音乐的名字！！！");
            return;
        }else{//遍历数组找对应信息
            for(var n = 0; n < this.MusicArr.length; n++){
                if((this.MusicArr[n].clip && name === this.MusicArr[n].clip.name) || name === this.MusicArr[n].musicName){
                    MusicInfo = this.MusicArr[n];
                    break;
                }
            }
        }
        if(MusicInfo == null){
            console.error("没找到要加载的普通音乐！！！");
        }else{
            if(MusicInfo.url){
                if(MusicInfo.url.indexOf("http") > -1){//远程加载
                    cc.loader.load(MusicInfo.url, (err, clip)=> {
                        if(err){
                            console.error(err.message || err);
                            return;
                        }
                        //记录当前的音频
                        this["DynamicMusic" + MusicInfo.musicName] = clip;
                    });
                }else{//本地加载
                    cc.loader.loadRes(MusicInfo.url, cc.AudioClip, (err, clip) => {
                        if(err){
                            console.error(err.message || err);
                            return;
                        }
                        //记录当前的音频
                        this["DynamicMusic" + MusicInfo.musicName] = clip;
                    });
                }
            }else{
                console.error("要加载的普通音乐url没找到！！！");
            }
        }
    }
});

/**音乐控制对外api合集，智能提示层
 * 
 * 1.背景音乐：
 * 
 * playBGM + 文件名字：播放指定背景音乐
 * 
 * 背景音乐名字列表：BGM
 * 
 * 2.普通音频：
 * 
 * play + 文件名字：播放指定音频
 * 
 * stop + 文件名字：停止指定音频
 * 
 * pause + 文件名字：暂停指定音频
 * 
 * resume + 文件名字：恢复指定音频
 * 
 * 普通音频名字列表：
 * 
 * blockBack  --  拼块回退
 * 
 * blockClick  --  拼块点击
 * 
 * blockPut  --  拼块放下
 * 
 * click  --  按钮点击
 * 
 * victory  --  胜利面板
 * 
 * winAnim  --  过关动画
*/
var GMusic = {

    /**播放背景音乐，3参数都可选，默认播放第一个背景音乐
     * 
     * name 背景音乐的名字，默认为第一个背景音乐 loop 背景音乐是否循环，默认true  volume 背景音乐的音量，默认1
     */
    playBGM(name, loop, volume){
        self.playBGM(name, loop, volume);
    },

    /**播放普通音乐，name必须，loop, volume可选
     * 
     * name 普通音乐的名字，  loop 普通音乐是否循环，默认false   volume 普通音乐的音量，默认1
     */
    play(name, loop, volume){
        self.play(name, loop, volume);
    },

    /**停止指定音频 name 音频名字，必需 */
    stop(name){
        self.stop(name);
    },

    /**暂停指定音频 name 音频名字，必需 */
    pause(name){
        self.pause(name);
    },

    /**恢复指定音频 name 音频名字，必需 */
    resume(name){
        self.resume(name);
    },

    /**暂停播放所有正在播放的普通音频 */
    pauseAllMusic(){
        self.pauseAllMusic();
    },

    /**恢复播放所有普通音频 */
    resumeAllMusic(){
        self.resumeAllMusic();
    },

    /**停止播放所有普通音频 */
    stopAllMusic(){
        self.stopAllMusic();
    },

    /**暂停正在播放的背景音乐 */
    pauseBGM(){
        self.pauseBGM();
    },

    /**恢复播放背景音乐 */
    resumeBGM(){
        self.resumeBGM();
    },

    /**停止正在播放的背景音乐 */
    stopBGM(){
        self.stopBGM();
    },

    /**播放背景音乐，只有一个背景音乐时的简略用法，有多个时默认播放第一个 */
    playBGM(){
        self.playBGM();
    },

    /**暂停播放所有声音，包括普通音频和背景音乐 */
    pauseAll(){
        self.pauseAll();
    },

    /**恢复播放所有声音，包括普通音频和背景音乐 */
    resumeAll(){
        self.resumeAll();
    },

    /**停止播放所有声音，包括普通音频和背景音乐 */
    stopAll(){
        self.stopAll();
    },

    /**设置静音模式 会暂停背景音乐 停止普通音频  不能播放和恢复所有音频*/
    muteMode(){
        self.muteMode();
    },

    /**恢复正常模式 会恢复背景音乐 可以播放所有音频 */
    normalMode(){
        self.normalMode();
    },

    /**模式切换，在静音模式和普通模式之间切换 */
    modeChange(){
        self.modeChange();
    },

    /**加载背景音乐 name背景音乐的名字，可选，默认为第一个背景音乐 */
    loadBGM(name){
        self.loadBGM(name);
    },

    /**加载普通音乐 name普通音乐的名字，必须 */
    loadMusic(name){
        self.loadMusic(name);
    },
};

window.GMusic = GMusic;
